<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    width="100%"
    :destroyOnClose="true"
    :closable="false"
  >
    <template #title>
      <Tag color="green" style="font-size: 16px">{{ title }}</Tag
      >表生成配置
    </template>
    <div>
      <div class="steps-box">
        <div class="steps-warp">
          <Steps :current="currentStep">
            <Step v-for="item in steps" :key="item.title" :title="item.title" />
          </Steps>
        </div>

        <div class="steps-action">
          <a-button danger @click="handleCoseDrawer">关闭</a-button>
          <a-button v-if="currentStep > 0" style="margin-left: 8px" @click="prev">上一步</a-button>
          <a-button
            v-if="currentStep < steps.length - 1"
            style="margin-left: 8px"
            type="primary"
            @click="next"
            >下一步</a-button
          >
          <a-button
            v-if="currentStep === steps.length - 1"
            style="margin-left: 8px"
            type="primary"
            @click="handleSubmit"
          >
            立即生成
          </a-button>
          <a-button
            v-if="currentStep === steps.length - 1"
            style="margin-left: 8px"
            type="primary"
            @click="handleSaveConfig"
          >
            保存配置
          </a-button>
        </div>
      </div>

      <div class="steps-content">
        <div v-if="currentStep === 0" class="form-warp">
          <BasicForm @register="registerBaseConfigForm">
            <template #moduleDirId="{ model, field }">
              <ApiTreeSelect
                :defaultValue="0"
                v-model:value="model[field]"
                :fieldNames="{ children: 'children', label: 'menuName', key: 'id', value: 'id' }"
                @change="treeSelectChange"
                :api="
                  () => {
                    return getMenuDir().then((res) => {
                      return [
                        {
                          menuName: '根模块目录',
                          key: 0,
                          id: 0,
                          children: res,
                        },
                      ];
                    });
                  }
                "
              />
            </template>
          </BasicForm>
        </div>
        <div v-else-if="currentStep === 1" class="form-warp">
          <BasicForm @register="registerPageConfigForm" />
        </div>
        <BasicTable
          v-else-if="currentStep === 2"
          @register="registerTable"
          :dataSource="tableData"
        />
      </div>
    </div>
  </BasicDrawer>
</template>

<script lang="ts" setup>
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { Tag, Steps, Step } from 'ant-design-vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useForm, BasicForm } from '/@/components/Form';
  import { useTable, BasicTable } from '/@/components/Table';
  import { baseFormSchema, pageFormSchema, fieldColumns } from './config.data';
  import {
    CodeGenConfigParams,
    GenTableConfig,
    TableFieldConfig,
    GenBaseConfig,
    ListConfig,
  } from '/@/api/gen/model/CodeGenModel';
  import { ref, unref, reactive } from 'vue';
  import { setGenConfig, getGenConfig } from '/@/utils/gen/config-cache';
  import { useLoading } from '/@/components/Loading';
  import { getKeyIdentityInfo, transferTableData } from '.';
  import ApiTreeSelect from '/@/components/Form/src/components/ApiTreeSelect.vue';
  import { getMenuDir } from '/@/api/sys/menu';

  interface GenApi {
    codeGenApi?: <T = any>() => Promise<T>;
    downloadZip?: <T = any>() => Promise<T>;
  }
  const { createMessage, createConfirm } = useMessage();
  const [openLoading, closeLoading, setLoadingTip] = useLoading({});
  const emit = defineEmits(['success', 'register', 'save']);
  const title = ref();
  const currentStep = ref(0);
  const tableData = ref<TableFieldConfig[]>();
  const baseFormData = ref<
    GenBaseConfig & {
      businessName?: string;
      moduleDirId?: number; // 同ListConfig中的pid
    }
  >();
  const pageFormData = ref<ListConfig>();
  const tableGenConfig = ref<CodeGenConfigParams>(); //外部传来的配置信息
  const genApi = reactive<GenApi>({});
  const steps = [
    {
      title: '基础配置',
    },
    {
      title: '页面配置',
    },
    {
      title: '字段配置',
    },
  ];

  const [
    registerBaseConfigForm,
    {
      resetFields: resetBaseConfigFields,
      setFieldsValue: setBaseConfigFieldsValue,
      validate: baseConfigValidate,
    },
  ] = useForm({
    schemas: baseFormSchema,
    showActionButtonGroup: false,
    rowProps: {
      gutter: 10,
    },
  });

  const [
    registerPageConfigForm,
    { setFieldsValue: setPageConfigFieldsValue, validate: pageConfigValidate },
  ] = useForm({
    schemas: pageFormSchema,
    showActionButtonGroup: false,
    rowProps: {
      gutter: 10,
    },
  });

  const [registerTable, { getDataSource }] = useTable({
    title: '字段列表',
    columns: fieldColumns,
    clickToRowSelect: false,
    useSearchForm: false,
    showTableSetting: false,
    bordered: true,
    showIndexColumn: false,
  });

  const [registerDrawer, { closeDrawer }] = useDrawerInner(async (data) => {
    resetBaseConfigFields();
    //重置步骤条
    currentStep.value = 0;
    genApi.codeGenApi = data.codeGenApi;
    genApi.downloadZip = data.downloadZip;
    const tableRow = data.row;
    tableGenConfig.value = data.genConfig;
    title.value = tableRow.name;
    const currentTableConfig = data.genConfig.genTableConfigs[0];
    pageFormData.value = currentTableConfig.listConfigEntity;
    baseFormData.value = data.genConfig.genBaseConfigEntity;
    setBaseConfigFieldsValue({
      ...baseFormData.value,
    });
    setPageConfigFieldsValue({
      ...pageFormData.value,
    });
    setBaseConfigFieldsValue({
      moduleDirId: currentTableConfig.listConfigEntity.pid,
      businessName: currentTableConfig.businessName || tableRow.comment || '',
    });
    //如果有缓存直接设置缓存的数据
    const key = `${data.genConfig.genDataSourceEntity.dbinfoId}::${data.genConfig.genDataSourceEntity.dbName}::${tableRow.name}`;
    if (getGenConfig(key)) {
      tableData.value = currentTableConfig.tableFieldConfig;
    } else {
      tableData.value = transferTableData(
        reactive([
          ...tableRow.fields,
          ...tableRow.commonFields.map((i) => {
            i.isCommon = true;
            return i;
          }),
        ]),
      );
    }
  });

  //模块目录树选择器点击事件
  function treeSelectChange(value, label, extra) {
    const menu = extra.triggerNode.props;
    if (menu.id !== 0) {
      setBaseConfigFieldsValue({
        moduleName: menu.name.toLocaleLowerCase(),
        moduleNameZh: menu.menuName,
      });
    }
  }

  //下一步
  const next = async () => {
    if (currentStep.value === 0) {
      baseFormData.value = await baseConfigValidate();
      setTimeout(() => {
        setPageConfigFieldsValue({
          ...pageFormData.value,
        });
      });
    } else if (currentStep.value === 1) {
      pageFormData.value = await pageConfigValidate();
    }
    currentStep.value++;
  };
  const prev = async () => {
    //上一步时也需要重设
    if (currentStep.value === 1) {
      pageFormData.value = await pageConfigValidate();
      setTimeout(() => {
        setBaseConfigFieldsValue({
          ...baseFormData.value,
        });
      });
    } else if (currentStep.value === 2) {
      setTimeout(() => {
        setPageConfigFieldsValue({
          ...pageFormData.value,
        });
      });
      tableData.value = getDataSource();
    }
    currentStep.value--;
  };

  function handleSubmit() {
    //保存配置
    saveConfig();
    //根据配置生成代码
    setLoadingTip('正在生成代码...');
    openLoading();
    (tableGenConfig.value!.genBaseConfigEntity.genMode === 'zip'
      ? genApi.downloadZip!
      : genApi.codeGenApi!)<boolean>().then((res) => {
      setTimeout(() => {
        closeLoading();
        res ? createMessage.success('生成成功') : createMessage.error('生成失败');
      }, 1000);
    });
    emit('success');
  }

  //保存配置
  function saveConfig() {
    //是否存在isQuery = false的
    pageFormData.value!.existSearchField = !!getDataSource().find((field) => field.isQuery);
    pageFormData.value!.pid = baseFormData.value!.moduleDirId!;
    //聚合配置
    const tableConfig: GenTableConfig = {
      businessName: baseFormData.value!.businessName,
      listConfigEntity: pageFormData.value!,
      tableComment: baseFormData.value!.businessName,
      tableFieldConfig: getDataSource(),
      tableName: title.value,
      ...getKeyIdentityInfo(getDataSource()),
    };
    tableGenConfig.value!.genBaseConfigEntity = unref(baseFormData.value) as GenBaseConfig;
    tableGenConfig.value!.genTableConfigs[0] = tableConfig;

    //给顶层的配置对象设置菜单父级id
    tableGenConfig.value!.pid = pageFormData.value!.pid;
    tableGenConfig.value!.sort = pageFormData.value!.sort;
    //缓存配置到本地 数据源id+数据库名+数据库表名称为key
    const key = `${tableGenConfig.value?.genDataSourceEntity.dbinfoId}::${tableGenConfig.value?.genDataSourceEntity.dbName}::${title.value}`;
    setGenConfig(key, unref(tableGenConfig));
  }

  //抽屉关闭
  function handleCoseDrawer() {
    if (currentStep.value === steps.length - 1) {
      createConfirm({
        iconType: 'warning',
        title: () => '关闭提示',
        content: () => '退出前请确保您已经保存生成配置！',
        okText: () => '立即关闭',
        cancelText: () => '取消',
        onOk: () => {
          console.log('conf====', tableGenConfig.value);
          closeDrawer();
          currentStep.value = 0;
        },
      });
    } else {
      closeDrawer();
      currentStep.value = 0;
    }
  }

  //保存配置
  function handleSaveConfig() {
    createConfirm({
      iconType: 'warning',
      title: () => '保存提示',
      content: () => '你确定要保存当前表生成设置吗？',
      okText: () => '立即保存',
      cancelText: () => '取消',
      onOk: () => {
        saveConfig();
        createMessage.success('保存成功');
        emit('save', unref(tableGenConfig));
      },
    });
  }
</script>

<style lang="less" scoped>
  .steps-content {
    margin-top: 16px;
    border: 1px dashed #e9e9e9;
    border-radius: 6px;
    background-color: #fafafa;
    min-height: calc(100vh - 64px - 55px - 77px - 32px - 16px);
  }

  .steps-action {
    position: absolute;
    top: 0;
    right: 10px;
  }

  .steps-box {
    width: 100%;
    position: relative;

    .steps-warp {
      width: 800px;
      margin: 0 auto;
    }
  }

  .form-warp {
    width: 60%;
    margin: 50px auto 0 auto;
  }
</style>
